﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AccountsViewModel.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="AccountsViewModel" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Modules.Core.Account.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.Diagnostics.Contracts;
    using System.Globalization;
    using System.Linq;
    using System.Windows.Input;
    using Business.Interfaces;
    using Common;
    using Common.BaseClasses;
    using Common.Services;
    using Hisaab.Client.Modules.Core.Account.Commands;
    using Hisaab.Common;
    using Microsoft.Practices.Prism;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.Regions;
    using Microsoft.Practices.ServiceLocation;
    using Model;

    /// <summary>
    /// Defines the <seealso cref="AccountsViewModel"/> type.
    /// </summary>
    public class AccountsViewModel : TabViewModel, INavigationAware
    {
        #region Data Member

        /// <summary>
        /// Session manager
        /// </summary>
        private readonly ISession _session;

        /// <summary>
        /// Account object
        /// </summary>
        private readonly IAccountManager _accountManager;

        /// <summary>
        /// Summary view model
        /// </summary>
        private AccountSummaryViewModel _summaryViewModel;

        /// <summary>
        /// Selected account
        /// </summary>
        private Account _selectedAccount;

        /// <summary>
        /// Accounts list
        /// </summary>
        private ObservableCollection<Account> _accounts;

        /// <summary>
        /// Member variable _editCommand
        /// </summary>
        private ICommand _editCommand;

        /// <summary>
        /// Member variable _deleteCommand
        /// </summary>
        private ICommand _deleteCommand;

        /// <summary>
        /// Member variable closeCommand
        /// </summary>
        private ICommand _closeCommand;

        #endregion Data Member

        /// <summary>
        /// Initializes a new instance of the <see cref="AccountsViewModel"/> class.
        /// </summary>
        public AccountsViewModel()
            : this(ServiceLocator.Current.GetInstance<IAccountManager>(), ServiceLocator.Current.GetInstance<ISession>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AccountsViewModel"/> class.
        /// </summary>
        /// <param name="accountManager">The account.</param>
        /// <param name="session">The session</param>
        public AccountsViewModel(IAccountManager accountManager, ISession session)
        {
            Contract.Requires<ArgumentNullException>(accountManager != null);
            Contract.Requires<ArgumentNullException>(session != null);

            _accountManager = accountManager;
            _session = session;
            Title = "Accounts";
        }

        #region Properties

        /// <summary>
        /// Gets the accounts.
        /// </summary>
        public ObservableCollection<Account> Accounts
        {
            get
            {
                if (_accounts == null)
                {
                    _accounts = new ObservableCollection<Account>(
                        _accountManager
                        .List(new Business.Entities.Account { UserId = _session.LoggedUser })
                        .Select(x => x.Map<Business.Entities.Account, Account>()));
                }

                return _accounts;
            }

            private set
            {
                if (value != _accounts)
                {
                    _accounts = value;

                    RaisePropertyChangedEvent("Accounts");
                }
            }
        }

        /// <summary>
        /// Gets or sets the selected account.
        /// </summary>
        /// <value>
        /// The selected account.
        /// </value>
        public Account SelectedAccount
        {
            get
            {
                return _selectedAccount;
            }

            set
            {
                if (value != _selectedAccount)
                {
                    _selectedAccount = value;
                    RaisePropertyChangedEvent("SelectedAccount");
                    SummaryViewModel = new AccountSummaryViewModel(value);
                }
            }
        }

        /// <summary>
        /// Gets or sets the summary view model.
        /// </summary>
        /// <value>
        /// The summary view model.
        /// </value>
        public AccountSummaryViewModel SummaryViewModel
        {
            get
            {
                return _summaryViewModel;
            }

            set
            {
                if (_summaryViewModel != value)
                {
                    _summaryViewModel = value;
                    RaisePropertyChangedEvent("SummaryViewModel");
                }
            }
        }

        /// <summary>
        /// Gets or sets the selected account view model.
        /// </summary>
        /// <value>
        /// The selected account view model.
        /// </value>
        public AccountSummaryViewModel SelectedAccountViewModel { get; set; }

        /// <summary>
        /// Gets the edit command.
        /// </summary>
        protected ICommand EditCommand
        {
            get
            {
                if (_editCommand == null)
                {
                    _editCommand = new DelegateCommand(EditAccount, CanEditAccount);
                }

                return _editCommand;
            }
        }

        /// <summary>
        /// Gets the delete command.
        /// </summary>
        protected ICommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                {
                    _deleteCommand = new DelegateCommand(DeleteAccount, CanDeleteAccount);
                }

                return _deleteCommand;
            }
        }

        /// <summary>
        /// Gets the delete command.
        /// </summary>
        protected ICommand CloseCommand
        {
            get
            {
                return _closeCommand;
            }
        }

        #endregion Properties

        /// <summary>
        /// Refreshes the list.
        /// </summary>
        /// <param name="obj">The object</param>
        public void RefreshList(object obj)
        {
            Accounts = new ObservableCollection<Account>(
                _accountManager
                    .List(new Business.Entities.Account { UserId = _session.LoggedUser })
                    .Select(x => x.Map<Business.Entities.Account, Account>()));
        }

        /// <summary>
        /// Edits the account.
        /// </summary>
        public void EditAccount()
        {
            if (SelectedAccount != null)
            {
                var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
                var query = new UriQuery { { "ID", SelectedAccount.AccountId.ToString(CultureInfo.InvariantCulture) } };
                var accountEditor = new Uri(AccountModule.AccountEditor + query, UriKind.Relative);
                regionManager.RequestNavigate(Regions.SecondaryRegion, accountEditor);
            }
        }

        /// <summary>
        /// Deletes the account.
        /// </summary>
        public void DeleteAccount()
        {
            if (SelectedAccount != null)
            {
                /*if (ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowMessage(
                       "Are you sure you want to delete selected account?",
                       "Hissab",
                       MessageBoxButtons.YesNo,
                       MessageBoxIcon.Question)
                       == DialogResult.Yes)
                {
                    _accountManager.Delete(SelectedAccount.Map<Account, Business.Entities.Account>());
                    Accounts.Remove(SelectedAccount);
                }*/
            }
        }

        /// <summary>
        /// Determines whether this instance [can edit tag].
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance [can edit tag]; otherwise, <c>false</c>.
        /// </returns>
        public bool CanEditAccount()
        {
            return true;
        }

        /// <summary>
        /// Determines whether this instance [can delete tag] the specified obj.
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance [can delete tag] the specified obj; otherwise, <c>false</c>.
        /// </returns>
        public bool CanDeleteAccount()
        {
            return true;
        }

        #region Implementation of INavigationAware

        /// <summary>
        /// Called when [navigated to].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
            var accountRibbonTab = new Uri(AccountModule.AccountTab, UriKind.Relative);
            regionManager.RequestNavigate(Regions.RibbonRegion, accountRibbonTab);

            AccountGlobalCommands.AddAccount.RegisterCommand(new AddAccountCommand());
            AccountGlobalCommands.EditAccount.RegisterCommand(EditCommand);
            AccountGlobalCommands.DeleteAccount.RegisterCommand(DeleteCommand);
        }

        /// <summary>
        /// Determines whether [is navigation target] [the specified navigation context].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        /// <returns>
        ///   <c>true</c> if [is navigation target] [the specified navigation context]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return false;
        }

        /// <summary>
        /// Called when [navigated from].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            AccountGlobalCommands.EditAccount.UnregisterCommand(EditCommand);
            AccountGlobalCommands.DeleteAccount.UnregisterCommand(DeleteCommand);
        }

        #endregion Implementation of INavigationAware
    }
}